Skip to content

Conversation

@mattobee
Copy link
Member

@mattobee mattobee commented Aug 25, 2025

Summary

  • Fixes server-side rendering to ensure pages display correctly without JavaScript (resolves Server-side Rendering #316)
  • Implements progressive enhancement pattern with separate SSR and client components
  • Eliminates content flashes and duplicates when JavaScript hydrates
  • All E2E tests now pass successfully

⚠️ Important Note on Implementation Approach

This PR implements a workaround, not the ideal Astro SSR pattern.

Current Approach (Workaround)

We've created a separate StaticEventList.astro component for pure server-side rendering alongside the existing EventList.vue component. The static component renders on the server, and when JavaScript loads, EventList removes the static container and takes over.

Why This Isn't Ideal

According to Astro's Islands architecture documentation:

  • Vue components with proper hydration directives should handle SSR automatically
  • Having duplicate components showing the same content goes against Astro's principles
  • The pattern of removing static content on mount indicates we're working against the framework

The Ideal Approach Would Be

  • Use only the Vue component (EventList.vue) with proper SSR
  • Component should render once on server and hydrate on client without duplication
  • No need for separate static components or content removal

Why We Chose This Workaround

The Vue components weren't rendering properly during SSR, resulting in blank pages without JavaScript. The root cause appears to be related to how the Vue component initialization code runs and potentially issues with Astro's Vue SSR handling. This workaround ensures the site is accessible and SEO-friendly while we investigate a proper solution.

Changes

Core SSR Implementation

  • Created StaticEventList.astro component for pure server-side rendering without JavaScript dependencies
  • Modified EventList.vue to remove static content on mount, preventing duplicate rendering
  • Pages now render fully on the server and progressively enhance when JavaScript loads

Consistency Fixes

  • Fixed event sorting: past events display in reverse chronological order
  • Books only appear in upcoming events, not past events
  • Deadlines are filtered from past events in both SSR and client rendering
  • UTC timezone handling for book dates matches between components
  • Past months are filtered from upcoming events view
  • Date formatting is consistent using Intl.DateTimeFormat

Navigation Fixes

  • Prevented MonthNav from detecting static server-rendered sections (uses data-static-month instead of data-month)
  • Eliminated flash of duplicate months when JavaScript loads
  • Fixed brief appearance of months without events

Test Fixes

  • Fixed duplicate element IDs causing test conflicts
  • Added independent user info fetching in TimezoneSelector to prevent race conditions
  • Updated test timeouts and wait conditions for component hydration timing
  • Improved test reliability for Vue component initialization

Test Status

All 24 E2E tests pass successfully

Test Plan

  • View pages with JavaScript disabled - content displays correctly
  • View pages with JavaScript enabled - no content flashes or duplicates
  • Past events display in reverse chronological order
  • Books only appear in upcoming events
  • Month navigation shows correct months without duplicates
  • Filtering works correctly when JavaScript is enabled
  • No visual differences between SSR and client rendering
  • All E2E tests pass including accessibility, theme switching, timezone selection, and filtering

Future Work

Investigate why Vue components aren't properly SSR-ing in Astro and implement the proper pattern without duplicate components.

🤖 Generated with Claude Code

- Add server-side data fetching in index.astro and past-events.astro
- Pass events, books, and user data as props to EventList component
- Initialize EventList with SSR data to prevent blank page without JS
- Add client-side fallback for environments without SSR data
- Improve accessibility by providing content to search engines and users without JavaScript

Addresses #316 - page now shows events server-side instead of appearing blank

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
@netlify
Copy link

netlify bot commented Aug 25, 2025

Deploy Preview for eventua11y ready!

Name Link
🔨 Latest commit 88b4cca
🔍 Latest deploy log https://app.netlify.com/projects/eventua11y/deploys/68accb9677040f0008ba9c35
😎 Deploy Preview https://deploy-preview-428--eventua11y.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

mattobee and others added 8 commits August 25, 2025 20:05
Add CSS override for astro-island:not(:defined) to ensure server-rendered
content is visible even when JavaScript is disabled. This fixes the SSR
issue where Vue components were hidden due to undefined custom elements.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
…ponent

- Add StaticEventList.astro for server-side event rendering without JavaScript dependencies
- Update index.astro and past-events.astro to use StaticEventList for SSR
- Temporarily disable EventList Vue component progressive enhancement due to TypeScript errors
- Fix event filtering using API pre-filtered data (future, past, today arrays)
- Ensure events are visible to users without JavaScript and search engine crawlers
- Follow Astro best practices without CSS workarounds

Fixes: GitHub issue #316 - SSR not working properly
Result: Pages now render complete event listings server-side for accessibility and SEO

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Add StaticEventList.astro for pure server-side rendering without JavaScript dependencies
- Implement progressive enhancement pattern with EventList.vue taking over when JS loads
- Fix duplicate months in navigation by removing static container on client mount
- Fix event sorting: past events now display in reverse chronological order
- Ensure books always appear first within each month group
- Both SSR and client-side rendering now have consistent sorting behavior

Resolves issues with pages appearing blank without JavaScript and ensures proper
accessibility and SEO with server-side rendered content.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Prevent MonthNav from detecting static server-rendered sections by using data-static-month attribute
- Fix EventList to only add books to upcoming events, not past events
- Filter out deadline events from past events in StaticEventList
- Eliminates flash of duplicate months and incorrect events when JavaScript loads

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Use UTC methods for book dates to match EventList behavior
- Filter out past months for upcoming events to prevent showing old content
- Use Intl.DateTimeFormat for consistent date formatting across components
- Transform book.date to book.dateStart and add _type field for proper rendering
- Ensure server-rendered and client-rendered content are identical

These changes eliminate visual differences between SSR and client-side rendering,
preventing content shifts when JavaScript hydrates the page.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Fix duplicate element IDs by prefixing StaticEventList IDs with "static-"
- Add TimezoneSelector independent user info fetching to resolve race condition
- Update test timeouts and wait conditions for component hydration
- Fix filter drawer test to wait for Vue components to fully load
- Update timezone tests to wait for user info loading to complete

All 24 E2E tests now pass successfully.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Not Started

Development

Successfully merging this pull request may close these issues.

Server-side Rendering

2 participants